#import "FGWindow.h"
#import <appkit/NXImage.h>
#import <appkit/NXBitmapImageRep.h>
#import <dpsclient/wraps.h>
#import <dpsclient/psops.h>
#import "Nutation.h"
#import <math.h>
#define NXSetWindowLevel _NXSetWindowLevel

// this window buffers the foreground (i.e. the targetGlyph) image
// of a GlyphView.  This image is kept in an offscreen window
// called "anImage", which is initially painted transparent.
// All drawing is directed at this offscreen window, and all
// compositing comes from it. If the ivar highlighted is YES,
// then the composite will be followed by a highlight.

@implementation FGWindow: BGWindow
{ id anImage ;
  BOOL highlighted ;
}

- erase: (NXRect *) aRect ;
{ // erase (to transparent white) aRect within my image
  [anImage lockFocus] ;
  PScompositerect(aRect->origin.x,aRect->origin.y,
   aRect->size.width, aRect->size.height, NX_CLEAR) ;
  [anImage unlockFocus] ;
  return self ;
}

- erase ;
{ // erase my image
  NXRect aRect = frame ;
  aRect.origin.x = aRect.origin.y = 0.0 ;
  return [self erase: &aRect] ;
}

- composite: (int) op fromRect: (const NXRect *) aRect
    toPoint: (const NXPoint *) aPnt ;
{ // actually composite from anImage
  NXRect bRect ;
  NXPoint bPnt ;
  bPnt.x = rint(aPnt->x) ;
  bPnt.y = rint(aPnt->y) ;
  bRect.size = aRect->size ;
  bRect.origin.x = rint(aRect->origin.x) ;
  bRect.origin.y = rint(aRect->origin.y) ;
  [anImage composite:op fromRect: &bRect toPoint: &bPnt] ;
  if(highlighted)
    PScompositerect(bPnt.x,bPnt.y,bRect.size.width,
      bRect.size.height, NX_HIGHLIGHT) ;
  return self ;
}

- composite: (int) op toPoint: (const NXPoint *) aPnt ;
{ // actually composite from anImage
  NXRect aRect = frame ;
  aRect.origin.x = aRect.origin.y = 0.0 ;
  return [self composite:op fromRect: &aRect toPoint: aPnt] ;
}

- composite: (int) op  ;
{ // actually composite from anImage
  NXPoint zeroPoint = {0.0,0.0} ;
  return [self composite:op toPoint: &zeroPoint] ;
}

- frame: (NXRect *) aFrame ;
{ // this is the "designated" initializer method
  // Frist, make the window which will be seen on-screen
  [super frame: aFrame] ;
  // make an offscreen window to buffer the image
  anImage = [[BGWindow alloc]
    initContent: aFrame
     style: NX_PLAINSTYLE
     backing: NX_RETAINED
     buttonMask: 0
     defer: NO] ;
  // paint anImage transparent
  [self erase] ;
  // for debugging, move offscreen window where it can be seen
  [anImage moveTo: 300.0 :0] ;
  // default is to be highlighted
  [self setHighlighted: YES] ;
  return self ;
}

- free ;
{ [anImage free] ;
  return [super free] ;
}

- image ;
{ return anImage ;
}

- (BOOL) lockFocus ;
{ // we actually lock focus on anImage
  return [anImage lockFocus] ;
}

- setHighlighted: (BOOL) YESorNO ;
{ highlighted = YESorNO ;
  return self ;
}

- sizeWindow:(NXCoord)width :(NXCoord)height ;
{ [anImage sizeWindow: width :height] ;
  [anImage erase] ;
  return [super sizeWindow: width :height] ;
}

- unlockFocus ;
{ NXRect aRect = frame ;
  // we actually unlock focus on anImage
  [anImage unlockFocus] ;
  // presumably, we have just some drawing, so
  // composite anImage over ourselves and
  // highlight if necessary
  [contentView lockFocus] ;
  aRect.origin.x = aRect.origin.y = 0.0 ;
  NXEraseRect(&aRect) ; // paintmyself opaque white
  [anImage composite: NX_SOVER toPoint: &aRect.origin] ;
  if(highlighted)
    PScompositerect(0.0,0.0,frame.size.width,
     frame.size.height, NX_HIGHLIGHT) ;
  [contentView unlockFocus] ;
  return self ;
}

@end